#ifndef UDP_RESPONSE_H
#define UDP_RESPONSE_H
#include "udppacket.h"
#include "base.h"

class UdpResponse: public UdpPacket
{
 protected:
  unsigned short m_usResponseId; /* = request id */
  int m_iId;                     /* for sliding window */
  int m_iSubResponseId; /* the ith answer to a single request */
  int m_iBlockId;	  /* the jth block in ith answer */
  int m_iTotalBlocks; /* total number of blocks to ith answer */
  unsigned short m_usBlockLength; /* the last block has length smaller */
  char m_block[BLOCK_LEN];			  /* be careful of the actual length */
 public:
  unsigned short & ResponseId() { return m_usResponseId; }
  int & ID() {return m_iId;}
  int & SubResponseId() { return m_iSubResponseId; }
  int & BlockId() { return m_iBlockId; } /* key has blockid = -1 */
  int & TotalBlocks() { return m_iTotalBlocks; }
  unsigned short& BlockLength() { return m_usBlockLength; }
  void SetBlock(const char * buf, unsigned short len);
  char * GetBlock() { return m_block; }
  bool IsEmptyResponse();
};

class UdpBlock
{
 private:
  char m_strBuf[BLOCK_LEN];
  size_t m_sLen;
 public:
  UdpBlock()
	{
	  m_sLen = 0;
	}
  ~UdpBlock()
	{
	}
  char * GetBuf() {return m_strBuf;}
  size_t& Length() { return m_sLen; }
  void Output() 
  {
    cout.write(m_strBuf, m_sLen); 
  }
  bool IsEmpty() { return m_sLen == 0; }
};

class Record
{
 public:
  Record()
	{
      m_iTotalBlocks = 0;
	}
  ~Record()
	{
      for (size_t i = 0; i < m_blocks.size(); i++)
        {
          if (m_blocks[i] != NULL)
            {
              delete m_blocks[i];
              m_blocks[i] = NULL;
            }
        }
	  m_blocks.clear();
	}

  bool IsEndofResponse()
  {
	return (m_iTotalBlocks == 0);
  }
  vector<UdpBlock* > m_blocks;
  int m_iTotalBlocks;
};
#endif
